﻿using Microsoft.AspNetCore.Identity;

namespace Devonline.Identity;

public interface IUserGroupStore<TUser, TKey> : IDisposable where TUser : class where TKey : IEquatable<TKey>, IConvertible
{
    /// <summary>
    /// Add the specified <paramref name="user"/> to the named group.
    /// </summary>
    /// <param name="user">The user to add to the named group.</param>
    /// <param name="group">The name of the group to add the user to.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
    Task<IdentityResult> AddToGroupAsync(TUser user, string group, CancellationToken cancellationToken = default);
    /// <summary>
    /// Add the specified <paramref name="user"/> to the named groups.
    /// </summary>
    /// <param name="user">The user to add to the named group.</param>
    /// <param name="groups">The name of the groups to add the user to.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
    Task<IdentityResult> AddToGroupsAsync(TUser user, IEnumerable<string> groups, CancellationToken cancellationToken = default);

    /// <summary>
    /// Remove the specified <paramref name="user"/> from the named group.
    /// </summary>
    /// <param name="user">The user to remove the named group from.</param>
    /// <param name="group">The name of the group to remove.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
    Task<IdentityResult> RemoveFromGroupAsync(TUser user, string group, CancellationToken cancellationToken = default);
    /// <summary>
    /// Remove the specified <paramref name="user"/> from the named groups.
    /// </summary>
    /// <param name="user">The user to remove the named group from.</param>
    /// <param name="groups">The name of the groups to remove.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
    Task<IdentityResult> RemoveFromGroupsAsync(TUser user, IEnumerable<string> groups, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets a list of group names the specified <paramref name="user"/> belongs to.
    /// </summary>
    /// <param name="user">The user whose group names to retrieve.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>The <see cref="Task"/> that represents the asynchronous operation, containing a list of group names.</returns>
    Task<IList<string>> GetUserGroupsAsync(TUser user, CancellationToken cancellationToken = default);

    /// <summary>
    /// Returns a list of Users who are members of the named group.
    /// </summary>
    /// <param name="group">The name of the group whose membership should be returned.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>
    /// The <see cref="Task"/> that represents the asynchronous operation, containing a list of users who are in the named group.
    /// </returns>
    Task<IList<TUser>> GetGroupUsersAsync(string group, CancellationToken cancellationToken = default);

    /// <summary>
    /// Returns a flag indicating whether the specified <paramref name="user"/> is a member of the given named group.
    /// </summary>
    /// <param name="user">The user whose group membership should be checked.</param>
    /// <param name="group">The name of the group to be checked.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
    /// <returns>
    /// The <see cref="Task"/> that represents the asynchronous operation, containing a flag indicating whether the specified <paramref name="user"/> is
    /// a member of the named group.
    /// </returns>
    Task<bool> IsInGroupAsync(TUser user, string group, CancellationToken cancellationToken = default);
}
